package com.cnap.controller;

import com.cnap.model.application.ApplicationDTO;
import com.cnap.model.application.ApplicationVO;
import com.cnap.model.application.QueryApplicationParam;
import com.cnap.model.application.UpdateApplicationParam;
import com.cnap.model.common.CommonResult;
import com.cnap.model.common.PageResult;
import com.cnap.model.log.OperationTypeEnum;
import com.cnap.service.ApplicationService;
import com.cnap.service.OperationLogService;
import com.cnap.utils.TokenUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * 应用服务控制类
 *
 * @author xc
 **/
@Api(tags = "应用管理")
@RestController
@RequestMapping("/api/application")
public class ApplicationController {
    /*
    应用上传
    应用管理
     */

    private static final Logger LOGGER = LoggerFactory.getLogger(ApplicationController.class);

    private final ApplicationService applicationService;
    private final OperationLogService operationLogService;

    @Autowired
    public ApplicationController(ApplicationService applicationService, OperationLogService operationLogService) {
        this.applicationService = applicationService;
        this.operationLogService = operationLogService;
    }

    /**
     * 查询应用列表
     *
     * @param queryApplicationParam 查询参数
     * @return 结果
     */
    @ApiOperation(value = "查询应用", notes = "查询应用", httpMethod = "POST")
    @PostMapping("/list")
    public CommonResult<PageResult<ApplicationVO>> listApplication(@Validated @RequestBody QueryApplicationParam queryApplicationParam) {
        LOGGER.info("[application]: query application {}", queryApplicationParam);
        PageResult<ApplicationVO> pageResult = applicationService.findByPage(queryApplicationParam);
        return CommonResult.success(pageResult);
    }

    /*
    初始化上传，前端需要获取压缩文件总大小，文件哈希值以及业务相关信息，通过初始化接口上传信息，接口返回id
    根据总大小以及分片大小，将文件分成若干片
    分片文件上传，并带有步骤1返回的id，表明是这个文件的分片信息
    循环步骤3，直至所有分片成功上传
    发送合并请求，带有步骤1返回的id
     */

    /**
     * 上传应用
     *
     * @param applicationDTO 应用信息
     * @return 应用id
     */
    @PostMapping("/upload")
    @ApiOperation(value = "上传应用", notes = "上传应用", httpMethod = "POST")
    public CommonResult<String> uploadApplication(@Validated @RequestBody ApplicationDTO applicationDTO) {
        LOGGER.info("[application]: upload application {}", applicationDTO);
        String id = applicationService.uploadApplication(applicationDTO);
        return CommonResult.success(id);
    }

    /*
    如果应用已被分解，则不能被更新分类信息。
    因为分类信息会被算法使用
     */

    /**
     * 更新应用信息
     *
     * @param updateApplicationParam 更新参数
     * @return 结果
     */
    @PostMapping("/update")
    @ApiOperation(value = "更新应用", notes = "更新应用", httpMethod = "POST")
    public CommonResult<String> updateApplication(@Validated @RequestBody UpdateApplicationParam updateApplicationParam) {
        LOGGER.info("[application]: update application {}", updateApplicationParam);
        boolean result = applicationService.updateApplication(updateApplicationParam);

        String message = TokenUtils.getUserName() + "更新了应用";
        operationLogService.saveOperationLog(OperationTypeEnum.OTHER.getType(), message);

        return result ? CommonResult.success("success") : CommonResult.failed("fail");
    }

    /**
     * 删除应用
     *
     * @param applicationId 应用id
     * @return 结果
     */
    @DeleteMapping("/delete/{id}")
    @ApiOperation(value = "删除应用", notes = "删除应用", httpMethod = "DELETE")
    public CommonResult<String> deleteApplication(@PathVariable("id") String applicationId) {
        LOGGER.info("[application]: delete application id={}", applicationId);
        boolean result = applicationService.deleteApplicationById(applicationId);

        String message = TokenUtils.getUserName() + "删除了应用";
        operationLogService.saveOperationLog(OperationTypeEnum.DELETE.getType(), message);

        return result ? CommonResult.success("success") : CommonResult.failed("fail");
    }

    /**
     * 查询需要拆解微服务的应用
     *
     * @param applicationParam 查询参数
     * @return 结果
     */
    @PostMapping("/list/split")
    @ApiOperation(value = "查询待拆解应用", notes = "查询待拆解应用", httpMethod = "POST")
    public CommonResult<PageResult<ApplicationVO>> listApplicationForSplit(@Validated @RequestBody QueryApplicationParam applicationParam) {
        LOGGER.info("[application]: query application for split, {}", applicationParam);
        PageResult<ApplicationVO> result = applicationService.findByPageForSplit(applicationParam);
        return CommonResult.success(result);
    }
}
